package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.*;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.BaseException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.*;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import lombok.extern.apachecommons.CommonsLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.integration.IntegrationProperties;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ShopcartMapper shopcartMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private OrderDetialMapper orderDetialMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderMapper ordersMapper;

    @Autowired
    private WebSocketServer webSocketServer;


    @Override
    public void reminder(Long id) {//id:订单id
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();
        String number = String.valueOf(id);
        // 根据订单号查询当前用户的订单
        Orders ordersDB = ordersMapper.getById(id);
        log.info("当前所需的订单：{}",ordersDB);
        // 通过WebSocket向客户端浏览器发送消息 type orderId content
        Map map = new HashMap<>();
        map.put("type",2);// 1 来单提醒;2  催单提醒
        map.put("orderId",id);
        map.put("content","订单号: " + ordersDB.getNumber());

        String jsonString = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(jsonString);
    }

    /**
     * 支付成功，修改订单状态
     *
     * @param outTradeNo
     */
    @Override
    public void paySuccess(String outTradeNo) {
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();

        // 根据订单号查询当前用户的订单
        Orders ordersDB = ordersMapper.getByNumberAndUserId(outTradeNo, userId);

        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        Orders orders = Orders.builder()
                .id(ordersDB.getId())
                .status(Orders.TO_BE_CONFIRMED)
                .payStatus(Orders.PAID)
                .checkoutTime(LocalDateTime.now())
                .build();

        ordersMapper.update(orders);
        // 通过WebSocket向客户端浏览器发送消息 type orderId content
        Map map = new HashMap<>();
        map.put("type",1);// 1 来单提醒
        map.put("orderId",ordersDB.getId());
        map.put("content","订单号: " + outTradeNo);

        String jsonString = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(jsonString);
    }

    @Override
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) {
        //当前登录用户id
        Long userId = BaseContext.getCurrentId();
        User user = userMapper.getById(userId);
        log.info("当前登录用户：{}",user);
        //生成空JSON，跳过微信支付流程
        JSONObject jsonObject=new JSONObject();

        if (jsonObject.getString( "code") != null && jsonObject.getString("code").equals("ORDERPAID")){
            throw new OrderBusinessException("该订单已支付");
        }
        OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
        log.info("微信支付结果：{}",jsonObject.getString("package"));
        vo.setPackageStr(jsonObject.getString("package"));
        log.info("service:订单支付结果：{}",vo);
//        paySuccess(ordersPaymentDTO.getOrderNumber());
        return vo;
    }

    /*完成订单*/
    @Override
    public void complete(Long id) {
        //查询订单
        Orders orders=new Orders();
        orders.setId(id);
        Orders order = orderMapper.list(orders).get(0);

        //订单状态改为4
        orders.setStatus(Orders.COMPLETED);
        orderMapper.update(orders);
    }

    /*派送订单*/
    @Override
    public void delivery(Long id) {
        //订单状态改为4
        //查询订单
        Orders orders=new Orders();
        orders.setId(id);
        Orders order = orderMapper.list(orders).get(0);

        //订单状态改为4
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        orderMapper.update(orders);
    }

    /*拒单*/
    @Override
    public void rejection(OrdersRejectionDTO ordersRejectionDTO) {
        //查询订单
        Orders orders=new Orders();
        orders.setId(ordersRejectionDTO.getId());
        Orders order = orderMapper.list(orders).get(0);

        //订单状态改为6
        orders.setStatus(Orders.CANCELLED);
        orders.setRejectionReason(ordersRejectionDTO.getRejectionReason());
        orderMapper.update(orders);
    }

    /*接单*/
    @Override
    public void confirm(Long id) {
        //查询订单
        Orders orders=new Orders();
        orders.setId(id);
        Orders order = orderMapper.list(orders).get(0);

        //订单状态改为3
        orders.setStatus(Orders.CONFIRMED);
        orderMapper.update(orders);
    }

    /*各个状态的订单数量统计*/
    @Override
    public OrderStatisticsVO statistics() {
        //查询订单各状态的数量
        OrderStatisticsVO orderStatisticsVO=orderMapper.statistics();
        log.info("订单各状态的数量：{}",orderStatisticsVO);
        return orderStatisticsVO;
    }

    /*订单搜索*/
    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {

        //通过PageHelper 进行分页
        PageHelper.startPage(ordersPageQueryDTO.getPage(),ordersPageQueryDTO.getPageSize());

        //将参数传到mapper层中进行搜索
        Page<Orders> page = (Page<Orders>) orderMapper.pageList(ordersPageQueryDTO);

        return new PageResult(page.getTotal(),page.getResult());



    }

    @Override
    @Transactional
    public void repetition(Long id) {
        Orders order = new Orders();
        order.setId(id);
        Orders order1 = orderMapper.list(order).get(0);
        //创建订单
        Orders orders = new Orders();
        BeanUtils.copyProperties(order1, orders);
        orders.setId(null);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(null);
        orders.setPayMethod(Orders.UN_PAID);
        orders.setPayStatus(Orders.UN_PAID);
        orders.setAmount(order1.getAmount());
        orders.setCancelTime( null);
        orders.setCancelReason( null);
        orders.setRejectionReason( null);
        orders.setEstimatedDeliveryTime( null);
        orders.setDeliveryTime( null);


        orderMapper.insert(orders);
        //查询订单详情
        List<OrderDetail> detailList = orderDetialMapper.list(order1.getId());
        detailList.forEach(detail -> detail.setOrderId(orders.getId()));
        //将订单详情复制到新订单中
        orderDetialMapper.insertBatch(detailList);
    }

    //通过id取消订单
    @Override
    public void cancel(OrdersCancelDTO ordersCancelDTO) {
        //查看是否有该订单，没有就抛异常
        Orders orders = new Orders();
        orders.setId(ordersCancelDTO.getId());
        List<Orders> list = orderMapper.list(orders);
        if (list == null || list.size() == 0) {
            throw new BaseException(MessageConstant.ORDER_NOT_FOUND);
        }
        //有数据就将其取消-》将订单状态改为取消（6）
        Orders orders1 = list.get(0);
        orders1.setStatus(Orders.CANCELLED);
        orders1.setCancelTime(LocalDateTime.now());
        orders1.setCancelReason(ordersCancelDTO.getCancelReason());
        orderMapper.update(orders1);

    }

    //通过id查询订单的详情信息
    @Override
    public OrderVO orderDetailById(Long id) {
        log.info("Service层接收到参数：{}",id);
        Orders orders=new Orders();
        orders.setId(id);
        List<Orders> list = orderMapper.list(orders);
        Orders order = list.get(0);
        log.info("得到查询到的订单信息：{}",order);
        List<OrderDetail> detailList = orderDetialMapper.list(id);
        log.info("得到查询到的订单详情信息：{}",detailList);
        //将查到的数据封装到OrderVO中
        OrderVO orderVO=new OrderVO();
        BeanUtils.copyProperties(order,orderVO);
        orderVO.setOrderDetailList(detailList);
        log.info("将封装后的数据封装到orderVO中：{}",orderVO);
        return orderVO;
    }

    //用户进行下单
    @Override
    @Transactional
    public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {
        /*处理异常，购物车为空，地址簿为空*/
        if (ordersSubmitDTO.getAddressBookId()==null){
            throw new AddressBookBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        //处理购物车为空
        Long currentId = BaseContext.getCurrentId();
        ShoppingCart shoppingCart=new ShoppingCart();
        shoppingCart.setUserId(currentId);
        List<ShoppingCart> list = shopcartMapper.list(shoppingCart);
        if (list==null|| list.size()==0){
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        //向订单表中插入一条数据
        Orders order=new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO,order);
        order.setOrderTime(LocalDateTime.now());
        order.setStatus(Orders.PENDING_PAYMENT);
        order.setPayStatus(Orders.UN_PAID);
        order.setNumber(String.valueOf(System.currentTimeMillis()));

        //获取地址簿中的信息
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        order.setPhone(addressBook.getPhone());
        order.setAddress(addressBook.getDetail());
        order.setConsignee(addressBook.getConsignee());
        order.setUserId(currentId);
        order.setAddressBookId(ordersSubmitDTO.getAddressBookId());
        order.setUserName(addressBook.getConsignee());

        orderMapper.insert(order);


        //向订单详情表中插入多条数据
        ShoppingCart cart = new ShoppingCart();
        cart.setUserId(currentId);
        List<ShoppingCart> carts = shopcartMapper.list(cart);
        List<OrderDetail> orderDetails = new ArrayList<>();
        for (ShoppingCart cart1 : carts) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart1,orderDetail);
            orderDetail.setOrderId(order.getId());
            orderDetails.add(orderDetail);
        }
        orderDetialMapper.insertBatch(orderDetails);
        //清空购物车
        shopcartMapper.clean(cart);
        OrderSubmitVO orderSubmitVO = new OrderSubmitVO();
        orderSubmitVO.setOrderTime(order.getOrderTime());
        orderSubmitVO.setOrderNumber(order.getNumber());
        orderSubmitVO.setOrderAmount(order.getAmount());
        orderSubmitVO.setId(order.getId());


        return orderSubmitVO;
    }

    /*订单历史查询*/
    @Override
    public PageResult historyOrders(Integer page, Integer pageSize, Integer status) {
        List<OrderVO> orderVOList =new ArrayList<>();
        //查询订单
        Orders orders = new Orders();
        orders.setUserId(BaseContext.getCurrentId());
        orders.setStatus(status);

        PageHelper.startPage(page,pageSize);

        List<Orders> ordersList = orderMapper.list(orders);

        log.info("订单分页查询结果：{}",ordersList);
        Page<Orders> ordersPage = (Page<Orders>) ordersList;
        log.info("orderService:订单分页查询，结果：{}", ordersList);
        for (Orders order : ordersList){
            OrderVO orderVO = new OrderVO();
            //添加订单菜品信息
            BeanUtils.copyProperties(order,orderVO);

            //添加详情菜品列表
            List<OrderDetail> detailList = orderDetialMapper.list(order.getId());
            orderVO.setOrderDetailList(detailList);

            log.info("orderService:查询结果：{}",orderVO);
            orderVOList.add(orderVO);
        }

        log.info("查询结果：{}",orderVOList);

        PageResult pageResult = new PageResult();
        pageResult.setTotal(ordersPage.getTotal());
        pageResult.setRecords(orderVOList);
        return pageResult;

    }
}
